﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web.Http;
using Kgb.Model.Models;
using Kgb.Service.Repository;
using Kgb.Service.Repository.Interface;
using System.Net;

namespace Kgb.Service.Controllers
{
    public class PlayersController : ApiController
    {
        //static readonly
        private IPlayerRepository _repository;

        public PlayersController()
        { 
            _repository = new PlayerRepository();
        }

        public IQueryable<Player> GetAllPlayers()
        {
            return _repository.GetAll();
            //var r = from p in _repository.GetAll()
            //        select new  Player
            //        {
            //            Id = p.Id
            //        ,
            //            SessionId = ""
            //        ,
            //            Name = p.Name
            //        ,
            //            State = p.State
            //        ,
            //            LobbyId = p.LobbyId
            //        ,
            //            RoomId = p.RoomId
            //        };

            //return r;
        }

        [HttpGet]
        public Lobby lobby(int id, string sessionId)
        {
            Guid sessionGuid;

            bool validGuid = Guid.TryParse(sessionId, out sessionGuid);

            if (!validGuid)
                throw new HttpResponseException(HttpStatusCode.NotFound);

            Player player = _repository.Get(id);
            if (player == null || player.LobbyId == null || !player.ValidateSession(sessionId))
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            LobbyRepository lobbyRepository = new LobbyRepository();

            var result = lobbyRepository.Get((int)player.LobbyId);

            if (result == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            return result;
        }
        
        [HttpGet]
        public Room Room(int id, string sessionId)
        {
            Guid sessionGuid;

            bool validGuid = Guid.TryParse(sessionId, out sessionGuid);

            if (!validGuid)
                throw new HttpResponseException(HttpStatusCode.NotFound); 
            
            Player player = _repository.Get(id);
            if (player == null || player.RoomId == null || !player.ValidateSession(sessionId))
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            RoomRepository roomRepository = new RoomRepository();

            var result = roomRepository.Get((int)player.RoomId);

            if (result == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

             return result;
        }

        [HttpGet]
        public Location Location(int id, string sessionId)
        {
            Guid sessionGuid;

            bool validGuid = Guid.TryParse(sessionId, out sessionGuid);

            if (!validGuid)
                throw new HttpResponseException(HttpStatusCode.NotFound);

            Player player = _repository.Get(id);
            if (player == null || !player.ValidateSession(sessionId))
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            
            LocationRepository locationRepository = new LocationRepository();

            var result = locationRepository.GetByPlayer(player);

            if (result == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            return result;
        }

        public Player GetPlayer(int id)
        {
            Player player = _repository.Get(id);
            if (player == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            return new Player(player.Name, "") { Id = player.Id, LobbyId = player.LobbyId, RoomId = player.RoomId, State = player.State};
        }

        public HttpResponseMessage<Player> PostPlayer(Player player)
        {
            try
            {
                player = _repository.Add(player);
            }
            catch (Exception ex)
            {
                if (ex is ArgumentException)
                    throw new HttpResponseException(ex.Message, HttpStatusCode.BadRequest);
                else
                    throw new HttpResponseException(ex.Message, HttpStatusCode.Conflict);
            }

            var response = new HttpResponseMessage<Player>(player, HttpStatusCode.Created);

            string uri = Url.Route(null, new { id = player.Id });
            response.Headers.Location = new Uri(Request.RequestUri, uri);
            return response;
        }

        public void PutPlayer(int id, Player player)
        {
            player.Id = id;
            if (!_repository.Update(player))
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
        }

        public HttpResponseMessage DeletePlayer(int id)
        {
            _repository.Remove(id);
            return new HttpResponseMessage(HttpStatusCode.NoContent);
        }
    }
}
